﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using blackhouse.BlackApart.Business;
using blackhouse.BlackApart.Business.Apartments;
using blackhouse.BlackApart.Business.Reservations;

namespace blackhouse.Aparts.Web.DataSources {

    [DataObject(true)]
    public abstract class WebReservations {

        #region Fields

        List<IWebReservation> reservation;

        #endregion

        #region Methods

        public abstract List<IWebReservation> Initialize();

        public List<IWebReservation> GetAllReservations(string sortColumns, int startRecord, int maxRecords) {
            if (this.reservation == null)
                this.reservation = this.Initialize();

            var q = from r in this.reservation
                    select r;

            if (!string.IsNullOrEmpty(sortColumns)) {
                sortColumns = sortColumns.ReplaceEx(" asc", "");
                IOrderedEnumerable<IWebReservation> oq = null;
                string[] columnNames = sortColumns.Split(',');
                foreach (string sortColumn in columnNames) {
                    string column = sortColumn.Trim().ToLowerInvariant();
                    bool desc = false;
                    if (column.EndsWith("desc")) {
                        desc = true;
                        column = column.Substring(0, column.Length - 5);
                    }
                    switch (column) {
                        case "reservationid":
                            Func<IWebReservation, int> sortFunc = (r => r.ReservationId);

                            if (oq == null) {
                                if (desc) oq = q.OrderByDescending(sortFunc);
                                else oq = q.OrderBy(sortFunc);
                            }
                            else {
                                if (desc) oq = oq.ThenByDescending(sortFunc);
                                else oq = oq.ThenBy(sortFunc);
                            }
                            break;
                        case "reservationnumber":
                            Func<IWebReservation, string> sortFunc2 = (r => r.ReservationNumber);

                            if (oq == null) {
                                if (desc) oq = q.OrderByDescending(sortFunc2);
                                else oq = q.OrderBy(sortFunc2);
                            }
                            else {
                                if (desc) oq = oq.ThenByDescending(sortFunc2);
                                else oq = oq.ThenBy(sortFunc2);
                            }
                            break;

                        case "apartment":
                            Func<IWebReservation, string> sortFunc3 = (r => r.GetGroupShortName());

                            if (oq == null) {
                                if (desc) oq = q.OrderByDescending(sortFunc3);
                                else oq = q.OrderBy(sortFunc3);
                            }
                            else {
                                if (desc) oq = oq.ThenByDescending(sortFunc3);
                                else oq = oq.ThenBy(sortFunc3);
                            }
                            break;

                        case "departuredate":
                            Func<IWebReservation, DateTime> sortFunc4 = (r => r.DepartureDate);

                            if (oq == null) {
                                if (desc) oq = q.OrderByDescending(sortFunc4);
                                else oq = q.OrderBy(sortFunc4);
                            }
                            else {
                                if (desc) oq = oq.ThenByDescending(sortFunc4);
                                else oq = oq.ThenBy(sortFunc4);
                            }
                            break;
                        default:
                            break;
                    }
                }
                if (oq != null)
                    q = oq;

            }
            return q.Skip(startRecord).Take(maxRecords).ToList();
        }

        public int SelectCount() {
            if (this.reservation == null)
                this.reservation = this.Initialize();
            return this.reservation.Count;
        }

        public IWebReservation GetReservation(int reservationId) {
            if (reservationId == 0) return null;
            IWebReservation reservation = Factory.Instance().GetWebReservation(reservationId);
            if (reservation.ReservationId != reservationId) return null;
            return reservation;
        }

        #endregion

    }
}